{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to use the prebuilt ReAct agent\n",
    "\n",
    "In this how-to we'll create a simple [ReAct](https://arxiv.org/abs/2210.03629) agent app that can check the weather. The app consists of an agent (LLM) and tools. As we interact with the app, we will first call the agent (LLM) to decide if we should use tools. Then we will run a loop:  \n",
    "\n",
    "1. If the agent said to take an action (i.e. call tool), we'll run the tools and pass the results back to the agent\n",
    "2. If the agent did not ask to run tools, we will finish (respond to the user)\n",
    "\n",
    "<div class=\"admonition warning\">\n",
    "    <p class=\"admonition-title\">Prebuilt Agent</p>\n",
    "    <p>\n",
    "Please note that here will we use a prebuilt agent. One of the big benefits of LangGraph is that you can easily create your own agent architectures. So while it's fine to start here to build an agent quickly, we would strongly recommend learning how to build your own agent so that you can take full advantage of LangGraph. Read <a href=\"https://langchain-ai.github.io/langgraphjs/tutorials/quickstart/#quickstart\"> this guide </a> to learn how to create your own ReAct agent from scratch.\n",
    "    </p>\n",
    "</div>   \n",
    "\n",
    "## Setup\n",
    "\n",
    "First, we need to install the required packages.\n",
    "\n",
    "```bash\n",
    "yarn add @langchain/langgraph @langchain/openai @langchain/core\n",
    "```\n",
    "\n",
    "This guide will use OpenAI's GPT-4o model. We will optionally set our API key\n",
    "for [LangSmith tracing](https://smith.langchain.com/), which will give us\n",
    "best-in-class observability."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ReAct Agent: LangGraphJS\n"
     ]
    }
   ],
   "source": [
    "// process.env.OPENAI_API_KEY = \"sk_...\";\n",
    "\n",
    "// Optional, add tracing in LangSmith\n",
    "// process.env.LANGCHAIN_API_KEY = \"ls__...\"\n",
    "// process.env.LANGCHAIN_CALLBACKS_BACKGROUND = \"true\";\n",
    "process.env.LANGCHAIN_CALLBACKS_BACKGROUND = \"true\";\n",
    "process.env.LANGCHAIN_TRACING_V2 = \"true\";\n",
    "process.env.LANGCHAIN_PROJECT = \"ReAct Agent: LangGraphJS\";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code\n",
    "\n",
    "Now we can use the prebuilt `createReactAgent` function to setup our agent:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { ChatOpenAI } from \"@langchain/openai\";\n",
    "import { tool } from '@langchain/core/tools';\n",
    "import { z } from 'zod';\n",
    "import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n",
    "\n",
    "const model = new ChatOpenAI({\n",
    "  model: \"gpt-4o\",\n",
    "});\n",
    "\n",
    "const getWeather = tool((input) => {\n",
    "  if (['sf', 'san francisco', 'san francisco, ca'].includes(input.location.toLowerCase())) {\n",
    "    return 'It\\'s 60 degrees and foggy.';\n",
    "  } else {\n",
    "    return 'It\\'s 90 degrees and sunny.';\n",
    "  }\n",
    "}, {\n",
    "  name: 'get_weather',\n",
    "  description: 'Call to get the current weather.',\n",
    "  schema: z.object({\n",
    "    location: z.string().describe(\"Location to get the weather for.\"),\n",
    "  })\n",
    "})\n",
    "\n",
    "const agent = createReactAgent({ llm: model, tools: [getWeather] });"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Usage\n",
    "\n",
    "First, let's visualize the graph we just created"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import * as tslab from \"tslab\";\n",
    "\n",
    "const graph = agent.getGraph();\n",
    "const image = await graph.drawMermaidPng();\n",
    "const arrayBuffer = await image.arrayBuffer();\n",
    "\n",
    "await tslab.display.png(new Uint8Array(arrayBuffer));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's run the app with an input that needs a tool call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "what is the weather in sf?\n",
      "-----\n",
      "\n",
      "[\n",
      "  {\n",
      "    name: 'get_weather',\n",
      "    args: { location: 'San Francisco, CA' },\n",
      "    type: 'tool_call',\n",
      "    id: 'call_wfXCh5IhSp1C0Db3gaJWDbRP'\n",
      "  }\n",
      "]\n",
      "-----\n",
      "\n",
      "It's 60 degrees and foggy.\n",
      "-----\n",
      "\n",
      "The weather in San Francisco is currently 60 degrees and foggy.\n",
      "-----\n",
      "\n"
     ]
    }
   ],
   "source": [
    "let inputs = { messages: [{ role: \"user\", content: \"what is the weather in SF?\" }] };\n",
    "\n",
    "let stream = await agent.stream(inputs, {\n",
    "  streamMode: \"values\",\n",
    "});\n",
    "\n",
    "for await (const { messages } of stream) {\n",
    "  let msg = messages[messages?.length - 1];\n",
    "  if (msg?.content) {\n",
    "    console.log(msg.content);\n",
    "  } else if (msg?.tool_calls?.length > 0) {\n",
    "    console.log(msg.tool_calls);\n",
    "  } else {\n",
    "    console.log(msg);\n",
    "  }\n",
    "  console.log(\"-----\\n\");\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's try a question that doesn't need tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "who built you?\n",
      "-----\n",
      "\n",
      "I was developed by OpenAI, an AI research and deployment company.\n",
      "-----\n",
      "\n"
     ]
    }
   ],
   "source": [
    "inputs = { messages: [{ role: \"user\", content: \"who built you?\" }] };\n",
    "\n",
    "stream = await agent.stream(inputs, {\n",
    "  streamMode: \"values\",\n",
    "});\n",
    "\n",
    "for await (\n",
    "  const { messages } of stream\n",
    ") {\n",
    "  let msg = messages[messages?.length - 1];\n",
    "  if (msg?.content) {\n",
    "    console.log(msg.content);\n",
    "  } else if (msg?.tool_calls?.length > 0) {\n",
    "    console.log(msg.tool_calls);\n",
    "  } else {\n",
    "    console.log(msg);\n",
    "  }\n",
    "  console.log(\"-----\\n\");\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Perfect! The agent correctly didn't call any tools and instead directly responded to the user."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "TypeScript",
   "language": "typescript",
   "name": "tslab"
  },
  "language_info": {
   "codemirror_mode": {
    "mode": "typescript",
    "name": "javascript",
    "typescript": true
   },
   "file_extension": ".ts",
   "mimetype": "text/typescript",
   "name": "typescript",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
